package com.yourenbang.lingyun.transaction.util;

import com.yourenbang.lingyun.core.util.StringUtil;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;

/**
　* @Description: 时间 util
　* @param
　* @author GuoliangDi
　*/
public class DateUtil extends org.apache.commons.lang3.time.DateUtils {
    public static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm" };


    /**
     * 得到当前日期localdatetime
     */
    public static LocalDateTime getLocalDateTime(String time, String pattern) {

        return LocalDateTime.parse(time, DateTimeFormatter.ofPattern(pattern));
    }

    public static LocalDateTime getLocalDateTime(String time) {

        return LocalDateTime.parse(time, DateTimeFormatter.ofPattern(parsePatterns[1]));
    }

    /**
     * 得到当前日期字符串格式（yyyy-MM-dd）
     */
    public static String getDate() {
        return getDate("yyyy-MM-dd");
    }

    /**
     * 得到当前日期字符串格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
     * @param
     * @return
     */
    public static String getDate(String pattern) {
        return DateFormatUtils.format(new Date(), pattern);
    }

    /**
     * 得到日期字符串默认格式（yyyy-MM-dd） pattern可以为："指定格式"
     */
    public static String formatDate(Date date, String pattern) {
        if (date == null) return "";
        if (pattern == null) pattern = "yyyy-MM-dd";
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return (sdf.format(date));
    }

    /**
     * 得到日期字符串默认格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String formatDateString(String date, Object... pattern) {
        String formatDate = null;
        try {
            if (pattern != null && pattern.length > 0) {
                formatDate = DateFormatUtils.format(formatDate(date, "yyyy-MM-dd HH:mm:ss"), pattern[0].toString());
            } else {
                formatDate = DateFormatUtils.format(formatDate(date, "yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd");
            }
        } catch (Exception e) {
            return formatDate;
        }
        return formatDate;
    }

    public static Date formatDate(String date, String format){
        try{
            if(StringUtil.isEmpty(format)){
                format = "yyyy-MM-dd HH:mm:ss";
            }
            return new SimpleDateFormat(format).parse(date);
        }catch(Exception e){
            e.printStackTrace();
        }
        return  new Date();
    }

    /**
     * 得到日期时间字符串，转换格式（时间戳）
     *
     * @param timestemp
     * @return
     */
    public static String formatDateTime3(long timestemp) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(new Date(timestemp));
    }

    /**
     * 得到当前时间字符串格式（HH:mm:ss）
     */
    public static String getTime() {
        return formatDate(new Date(), "HH:mm:ss");
    }

    /**
     * 得到当前日期和时间字符串格式（yyyy-MM-dd HH:mm:ss）
     */
    public static String getDateTime() {
        return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 得到当前日期和时间字符串格式（yyyy-MM-dd HH:mm:ss）
     */
    public static String getDateTime2() {
        return formatDate(new Date(), "yyyyMMddHHmmss");
    }

    /**
     * 得到当前年份字符串格式（yyyy）
     */
    public static String getYear() {
        return formatDate(new Date(), "yyyy");
    }

    /**
     * 得到当前月份字符串格式（MM）
     */
    public static String getMonth() {
        return formatDate(new Date(), "MM");
    }

    /**
     * 得到指定日期字符串的当前月份（MM）
     *
     * @param date
     * @return
     */
    public static String getMonth(Date date) {
        return formatDate(date, "MM");
    }

    /**
     * 得到指定日期字符串的当前月份（MM）
     *
     * @param datestr
     * @return
     */
    public static String getMonth(String datestr) {
        return formatDate(parseDate(datestr), "MM");
    }

    /**
     * 得到当天字符串格式（dd）
     */
    public static String getDay() {
        return formatDate(new Date(), "dd");
    }

    /**
     * 得到当前星期字符串格式（E）星期几
     */
    public static String getStringWeek() {
        return formatDate(new Date(), "E");
    }

    /**
     * 得到当前星期 数字
     * @param date
     * @return 返回1是星期一、2是星期二、3是星期三、4是星期四、5是星期五、6是星期六、7是星期日
     */
    public static int getIntWeek(Date date){
        Calendar cal = Calendar.getInstance();
        if (date == null) {
            cal.setTime(new Date(System.currentTimeMillis()));
        }else {
            cal.setTime(date);
        }
        int tempWeek = cal.get(Calendar.DAY_OF_WEEK);
        if(tempWeek == 1){
            return 7;
        }else{
            return tempWeek - 1;
        }
    }

    /**
     * 字符串转化为日期
     * { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm" }
     *
     * @param str
     * @return
     */
    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }
        try {
            return parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取过去的天数
     *
     * @param date
     * @return
     */
    public static long pastDays(Date date) {
        long t = new Date().getTime() - date.getTime();
        return t / (24 * 60 * 60 * 1000);
    }

    /**
     * 获取指定日期当月天数的数组
     *
     * @param datestr
     * @return
     */
    public static String[] getMonthDayArray(String datestr) {
        SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM");
        Calendar rightNow = Calendar.getInstance();
        try {
            rightNow.setTime(simpleDate.parse(datestr.substring(0, 4) + "-" + datestr.substring(4, 6)));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int day = rightNow.getActualMaximum(Calendar.DAY_OF_MONTH);//根据年月获取月份天数
        String[] days = new String[day];
        for (int i = 0; i < day; i++) {
            if (i < 10) {
                if (i == 9) {
                    days[i] = datestr.substring(4, 6) + "-" + String.valueOf(i + 1);
                } else {
                    days[i] = datestr.substring(4, 6) + "-" + "0" + (i + 1);
                }
            } else {
                days[i] = datestr.substring(4, 6) + "-" + String.valueOf(i + 1);
            }
        }
        return days;
    }

    /**
     * 获取指定日期当月天数
     *
     * @param datestr
     * @return
     */
    public static int getMonthDays(String datestr) {
        SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM");
        Calendar rightNow = Calendar.getInstance();
        try {
            rightNow.setTime(simpleDate.parse(datestr.substring(0, 4) + "-" + datestr.substring(4, 6)));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return rightNow.getActualMaximum(Calendar.DAY_OF_MONTH);//根据年月获取月份天数
    }

    /**
     * 获取date 当天的零点
     * @param date
     * @return
     */
    public static Date getDateStart(Date date) {
        Date datetemp = date;
        if (date == null) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            datetemp = sdf.parse(formatDate(date, "yyyy-MM-dd") + " 00:00:00");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return datetemp;
    }

    /**
     * 获取date 当天的最大时间23点59分59秒
     * @param date
     * @return
     */
    public static Date getDateEnd(Date date) {
        Date datetemp = date;
        if (date == null) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            datetemp = sdf.parse(formatDate(date, "yyyy-MM-dd") + " 23:59:59");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return datetemp;
    }

    /**
     * 获取两个时间的误差 单位是秒
     * @param before
     * @param after
     * @return
     */
    public static Long getStringTimeDifference(String before,String after){
        return getTimeDifference(parseDate(before),parseDate(after));
    }

    /**
     * 返回两个时间的误差 单位是秒
     * @param before
     * @param after
     * @return
     */
    public static Long getTimeDifference(Date before,Date after){
        return (after.getTime()-before.getTime())/1000;

    }

    /**
     * 计算两个日期之间相差的天数
     * @param start 开始时间
     * @param end 结束时间
     * @return 天数
     */
    public static int daysBetween(Date start, Date end) {
        Calendar calst = Calendar.getInstance();
        Calendar caled = Calendar.getInstance();
        calst.setTime(start);
        caled.setTime(end);
        // 设置时间为0时
        calst.set(Calendar.HOUR_OF_DAY, 0);
        calst.set(Calendar.MINUTE, 0);
        calst.set(Calendar.SECOND, 0);
        caled.set(Calendar.HOUR_OF_DAY, 0);
        caled.set(Calendar.MINUTE, 0);
        caled.set(Calendar.SECOND, 0);
        // 得到两个日期相差的天数
        return ((int) (caled.getTime().getTime() / 1000) - (int) (calst.getTime().getTime() / 1000)) / 3600 / 24;
    }

    /**
     * 计算两个日期之间相差的天数
     * @param before
     * @param after
     * @return int
     * @throws ParseException
     */
    public static int daysBetween(String before, String after) {
        Date beforeDate = new Date();
        Date afterDate = new Date();
        DateFormat df = DateFormat.getDateInstance();
        try {
            beforeDate = df.parse(before);
            afterDate = df.parse(after);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calst = Calendar.getInstance();
        Calendar caled = Calendar.getInstance();
        calst.setTime(beforeDate);
        caled.setTime(afterDate);
        // 设置时间为0时
        calst.set(Calendar.HOUR_OF_DAY, 0);
        calst.set(Calendar.MINUTE, 0);
        calst.set(Calendar.SECOND, 0);
        caled.set(Calendar.HOUR_OF_DAY, 0);
        caled.set(Calendar.MINUTE, 0);
        caled.set(Calendar.SECOND, 0);
        // 得到两个日期相差的天数
        return ((int) (caled.getTime().getTime() / 1000) - (int) (calst.getTime().getTime() / 1000)) / 3600 / 24;
    }

    /**
     *字符串的日期格式的计算
     */
    public static int dayBetween(String smdate,String bdate) throws ParseException{
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(sdf.parse(smdate));
        long time1 = cal.getTimeInMillis();
        cal.setTime(sdf.parse(bdate));
        long time2 = cal.getTimeInMillis();
        long between_days=(time2-time1)/(1000*3600*24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 获取当天剩余的时间 从当前时间到24点的时间差
     * @return 返回的时间差 单位是秒
     */
    public static long getTodaySurplusTime(){
        Date nowDate = new Date();
        return (getDateEnd(nowDate).getTime() - nowDate.getTime())/1000;
    }

    /**
     * java计算两个时间相差（天、小时、分钟、秒）
     * @param startTime
     * @param endTime
     * @param format
     * @param str
     * @return
     */
    public static long dateDiff(String startTime, String endTime, String format, String str) {
        // 按照传入的格式生成一个simpledateformate对象
        SimpleDateFormat sd = new SimpleDateFormat(format);
        long nd = 1000 * 24 * 60 * 60;// 一天的毫秒数
        long nh = 1000 * 60 * 60;// 一小时的毫秒数
        long nm = 1000 * 60;// 一分钟的毫秒数
        long ns = 1000;// 一秒钟的毫秒数
        long diff;
        long day = 0;
        long hour = 0;
        long min = 0;
        long sec = 0;
        // 获得两个时间的毫秒时间差异
        try {
            diff = sd.parse(endTime).getTime() - sd.parse(startTime).getTime();
            day = diff / nd;// 计算差多少天
            hour = diff % nd / nh + day * 24;// 计算差多少小时
            min = diff % nd % nh / nm + day * 24 * 60;// 计算差多少分钟
            sec = diff % nd % nh % nm / ns;// 计算差多少秒
            // 输出结果
            //System.out.println("时间相差：" + day + "天" + (hour - day * 24) + "小时" + (min - day * 24 * 60) + "分钟" + sec + "秒。");
            //System.out.println("hour=" + hour + ",min=" + min);
            if (str.equalsIgnoreCase("h")) {
                return hour;
            } else {
                return min;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        if (str.equalsIgnoreCase("h")) {
            return hour;
        } else {
            return min;
        }
    }

    /**
     * 将形如yyyyMMddHHmmss的形式变成yyyy-MM-dd HH:mm:ss
     * @param datestr
     * @return
     */
    public static String getFormatDateString(String datestr) {
        return datestr.substring(0, 4) + "-" + datestr.substring(4, 6) + "-" + datestr.substring(6, 8) + " " + datestr.substring(8, 10) + ":" + datestr.substring(10, 12) + ":" + datestr.substring(12, 14);
    }


    /**
     * 日期比较 第一个时间比第二个时间大,则返回true
     * @param oldDate
     * @param newDate
     * @return
     */
    public static boolean compare(Date oldDate,Date newDate){
        if(oldDate.getTime() > newDate.getTime()){
            return true;
        }else{
            return false;
        }
    }

    /**
     * 是否同一天
     * @param sDate1
     * @param sDate2
     * @return
     */
    public static boolean isSameDay(String sDate1,String sDate2){
        sDate1 = sDate1.substring(0, 10);
        sDate2 = sDate2.substring(0, 10);
        return sDate1.equals(sDate2);
    }

    /**
     * 从当前时间往前推几天
     * @param day
     * @return
     */
    public static String getStringBeforeDay(Integer day){
        return formatDate(getBeforeDay(new Date(),day),"yyyy-MM-dd");
    }

    /**
     * 从currentDate 往前推day天
     * @param currentDate
     * @param day
     * @return
     */
    public static String getStringBeforeDay(Date currentDate,Integer day){
        return formatDate(getBeforeDay(currentDate,day),"yyyy-MM-dd");
    }

    /**
     * 往前推多少天
     * @param currentDate
     * @param day 单位是天
     * @return
     */
    public static Date getBeforeDay(Date currentDate,Integer day){
        if(day == null){
            return null;
        }
        return getBeforeDateTime(currentDate,day*24*60);
    }

    /**
     * 从currentDate往前推多长时间 单位是分钟
     * @param currentDate
     * @param min 单位是分钟
     * @return
     */
    public static Date getBeforeDateTime(Date currentDate,Integer min){
        if(currentDate == null || min == null){
            return null;
        }
        Long current = currentDate.getTime();
        return new Date(current - (Long.parseLong(min+"") * 60 * 1000));
    }

    /**
     * 获取距离明天还有多少秒
     * @return
     */
    public static long getLastTime(){
        long milliSecondsLeftToday = 86400000 - DateUtils.getFragmentInMilliseconds(Calendar.getInstance(), Calendar.DATE);
        if(milliSecondsLeftToday == 0){
            return 0;
        }else {
            return milliSecondsLeftToday / 1000;
        }
    }

    /**
     * 获取上个月的月份
     * @param month 往前推几个月
     * @return yyyy-MM
     */
    public static String getFrontMonth(int month) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH,-month);
        return formatDate(cal.getTime(),"yyyy-MM");
    }

    /**
     * 从当前时间往前推hour小时
     * @param hour
     * @return
     */
    public static String getBeforeHour(int hour){
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.HOUR,-hour);
        return formatDate(cal.getTime(),"yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 从当前时间往前推hour个小时
     * @param nowDate
     * @param hour
     * @return
     */
    public static String getBeforeHour(Date nowDate,int hour){
        Calendar cal = Calendar.getInstance();
        cal.setTime(nowDate);
        cal.add(Calendar.HOUR,-hour);
        return formatDate(cal.getTime(),"yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 获取从startTime 到 endTime 之间的时间数组
     *  注意: 不包含endTime
     * @param startTime
     * @param endTime
     * @return
     */
    public static String[] getStartToEndHour(String startTime, String endTime) {
        Date startDate = parseDate(startTime);
        Date endDate = parseDate(endTime);
        return getStartToEndHour(startDate,endDate);
    }

    /**
     * 获取从startTime 到 endTime 之间的时间数组
     *  注意: 不包含endTime
     * @param startTime
     * @param endTime
     * @return
     */
    public static String[] getStartToEndHour(Date startTime, Date endTime) {
        long time = endTime.getTime() - startTime.getTime();
        int hour = (int) (time/1000/60/60);
        String[] hours = new String[hour];
        for(int i=0; i < hour; i++){
            hours[i] = getBeforeHour(startTime,-i);
        }
        return hours;
    }

    /**
     * 获取从N天前 到现在 的日期 数组
     * @param day
     * @return
     */
    public static String[] getBeforeDayToNowDay(int day){
        String[] days = new String[day];
        for(int i=day; i>0; i--){
            days[day-i] = getStringBeforeDay(i);
        }
        return days;
    }

    /**
     * 获取从开始时间到当前时间为止 的所有时间数组
     * @param startTime
     * @return
     */
    public static String[] getStartToNowDay(String startTime) {
        Date startDate = parseDate(startTime);
        long time = new Date().getTime() - startDate.getTime();
        int day = (int) (time/1000/60/60/24);
        String[] days = new String[day];
        for(int i=0; i < day; i++){
            days[i] = getStringBeforeDay(startDate,-i);
        }
        return days;
    }

    /**
     * 往前推month 个月 获取
     * @param month
     * @return
     */
    public static String[] getNowBeforeMonth(int month) {
        String[] months = new String[month];
        Calendar cal = null;
        for(int i=0;i<month;i++){
            cal = Calendar.getInstance();
            cal.add(Calendar.MONTH,-(month-i));
            months[i] = DateUtil.formatDate(cal.getTime(),"yyyy-MM");
        }
        return months;
    }

    /**
     * 从当前时间往前推month个月
     * @param month
     * @return
     */
    public static String getBeforeMonth(int month) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH,-month);
        return formatDate(cal.getTime(),"yyyy-MM");
    }

    /**
     * 获取指定日期的开始日期 00:00:00或者结束日期23:59:59
     * @param date
     * @flag 0 返回yyyy-MM-dd 00:00:00日期<br>
     *       1 返回yyyy-MM-dd 23:59:59日期
     * @return
     */
    public static Date weeHours(Date date, int flag) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        int minute = cal.get(Calendar.MINUTE);
        int second = cal.get(Calendar.SECOND);
        //时分秒（毫秒数）
        long millisecond = hour*60*60*1000 + minute*60*1000 + second*1000;
        //凌晨00:00:00
        cal.setTimeInMillis(cal.getTimeInMillis()-millisecond);

        if (flag == 0) {
            return cal.getTime();
        } else if (flag == 1) {
            //凌晨23:59:59
            cal.setTimeInMillis(cal.getTimeInMillis()+23*60*60*1000 + 59*60*1000 + 59*1000);
        }
        return cal.getTime();
    }

}
